package com.project.code.luck.service.impl;

import com.project.code.luck.entity.po.LuckUser;
import com.project.code.luck.mapper.LuckUserMapper;

import com.project.code.luck.service.LuckUserService;

import com.project.code.luck.entity.params.LuckUserPageParams;
import com.project.code.luck.entity.po.LuckUser;
import com.project.code.luck.mapper.LuckUserMapper;
import com.project.code.luck.service.LuckUserService;

import com.project.common.constant.NumberConstants;
import com.project.common.enums.DelFlagEnum;
import com.project.common.utils.ServletUtils;
import com.project.common.utils.bean.CopyObjectUtils;
import com.project.common.utils.number.NumberUtils;
import com.project.framework.web.service.TokenService;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.common.collect.Lists;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

/**
 * 好运用户 Service业务层处理
 *
 * @author WangYan
 * @date 2023-05-14
 */
@Slf4j
@Service
public class LuckUserServiceImpl implements LuckUserService  {

    @Resource
    private LuckUserMapper luckUserMapper;
    @Resource
    private TokenService tokenService;



    @Override
    public int insert(LuckUser po) {
        po.setId(null);
        po.setCreateTime(new Date());
        po.setUpdateTime(new Date());
//        po.setCreateUser(tokenService.getLoginUser(ServletUtils.getRequest()).getUsername());
        return luckUserMapper.insert(po);
    }

    @Override
    public int updateById(LuckUser po) {
        if (NumberUtils.isEntity(po.getId())) {
            throw new RuntimeException("数据ID不存在");
        }
        if (delete(Lists.newArrayList(po.getId())) > NumberConstants.ZERO) {
            return insert(po);
        }
        return NumberConstants.ZERO;
    }

    @Override
    public int delete(List<Long> ids) {
        int deleteCount = 0;
        for (Long id : ids) {
            deleteCount = deleteCount + luckUserMapper.updateById(LuckUser.builder()
                    .id(id)
                    .updateTime(new Date())
                    .updateUser(tokenService.getLoginUser(ServletUtils.getRequest()).getUsername())
                    .delFlag(DelFlagEnum.HAS_DELETED.getCode())
                    .build());
        }
        return deleteCount;
    }

    @Override
    public <Vo> Vo read(Long id, Class<Vo> resultClass) {
        LuckUser data = luckUserMapper.selectById(id);
        if (data == null) {
            throw new RuntimeException("根据id查询不到数据");
        }
        return CopyObjectUtils.copyAtoB(data, resultClass);
    }

    @Override
    public <Vo> List<Vo> list(LuckUserPageParams params, Class<Vo> resultClass) {
        LambdaQueryWrapper<LuckUser> wrapper = Wrappers.lambdaQuery(LuckUser.class);
        wrapper.eq(LuckUser::getDelFlag, DelFlagEnum.NOT_DELETED.getCode());
        //TODO 前端的条件查询
        List<LuckUser> page = luckUserMapper.selectList(wrapper);
        return CopyObjectUtils.copyAListToBList(page, resultClass);
    }

    @Override
    public void oom() {
        System.out.println("开始模拟内存泄漏...");

        int operationCount = 0;

        try {
            while (true) {
                operationCount++;

                // ✅ 正常操作：创建临时对象（会被GC回收）
                createTemporaryObjects();

                // ❌ 危险操作：向静态列表添加对象（内存泄漏！）
                byte[] leakyData = new byte[1024 * 1024]; // 1兆的数据
                LuckData.LEAKY_LIST.add(leakyData);

                System.out.println("第 " + operationCount + " 次操作 - 泄漏列表大小: " + LuckData.LEAKY_LIST.size());

                // 慢一点，方便观察
                Thread.sleep(100);
            }
        } catch (OutOfMemoryError e) {
            System.out.println("=== 发生内存溢出 ===");
            System.out.println("总共执行了 " + operationCount + " 次操作");
            System.out.println("泄漏列表中积累了 " + LuckData.LEAKY_LIST.size() + " 个对象");
            System.out.println("这些对象永远无法被回收！");
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }

    public static class LuckData{
        // ❌ 问题就在这里：静态集合会一直存活，里面的对象永远无法被垃圾回收
        static List<byte[]> LEAKY_LIST = new ArrayList<>();

    }
    // 这个方法创建的对象会被正常回收
    private static void createTemporaryObjects() {
        List<String> tempList = new ArrayList<>();
        for (int i = 0; i < 50; i++) {
            tempList.add("temp_data_" + i);
        }
        // tempList 在方法结束后就会失去引用，可以被GC回收
    }

}
